Software applications that rely on automatic memory management are becoming more and more prevalent. Such applications may be implemented as traditional consumer desktop applications, in large scale data analysis computing systems, on high-performance web servers, on financial trading platforms, and can be included in ever-more demanding (e.g., memory intensive) websites. Such applications are even available for use on the billions of mobile phones and other mobile computing devices that exist world-wide, as well as for implementation by embedded computing devices. Accordingly, reducing the costs (e.g., performance costs) of automatic memory management is of principal importance in best utilizing computing resources across the entire spectrum of available devices, and for achieving improved throughput (performance), so as to improve the experience of users of such applications.
Many automatic memory management systems utilize garbage collection, such as may be implemented using a generational garbage collector, to remove memory objects that are no longer needed (e.g., outdated objects) by a given application, as part of managing memory that is assigned to the application by a computing device on which the application (program) is executing (running). Garbage collection (e.g., generational garbage collection) can also be used to defragment a block of memory that is associated with a given program. Such a defragmentation process can group (move) live (active) memory objects together in memory (e.g., in contiguous blocks of memory) and, as a result, free up larger blocks (sections, chunks, etc.) of available (free, unassigned, and so forth) memory space by eliminating portions of free memory that are located between live objects (resulting in fragmented memory). These portions of unused (fragmented) memory may, for instance, be associated with objects that are no longer being used by the given application (which can also be referred to as “dead” objects).
Garbage collection, however, can introduce overhead in the associated application's main execution path. While some garbage collection work can be done incrementally, in parallel with the application, or even concurrently with the application, the performance costs associated with garbage collection still remain. Such performance costs can be associated with moving (copying) memory objects from one generation (e.g., a young garbage collection generation) to a second generation (an old or older garbage collection generation). This performance cost can be even more apparent in garbage collectors that target low pause time (e.g., where garbage collection does not affect a user's perception of performance during application execution) and/or for applications where a relatively high percentage of allocated memory objects “survive” a given garbage collection generation (e.g., remain live), and have to be moved from one a young or younger generation to an old, or older generation during a garbage collection process.